class FormStorage {
    formId: string | number;
    formData: any;
    storageKey: string;
    channel: BroadcastChannel;
    constructor(formId: string | number, formData: any) {
        this.formId = formId;
        this.formData = formData;
        this.storageKey = `formData_${formId}`;
        this.channel = new BroadcastChannel("formData_channel");
        this.debounce(this.saveData, 2000).bind(this);
        FormStorageManager.regist(this);

        this.channel.onmessage = event => {
            const { id, data } = JSON.parse(event.data);
            if (id === this.formId) {
                this.echoData(data);
            } else if (id === "clearAll") {
                this.clearData();
            }
        };
    }

    init() {
        // 初始化表单数据
        this.loadData();
    }
    saveData() {
        localStorage.setItem(this.storageKey, JSON.stringify(this.formData));
        this.channel.postMessage(
            JSON.stringify({
                id: this.formId,
                data: this.formData,
            })
        );
    }
    loadData() {
        const saveData = JSON.parse(localStorage.getItem(this.storageKey) as string);
        if (saveData) {
            for (const key in saveData) {
                if (Object.prototype.hasOwnProperty.call(saveData, key)) {
                    this.formData[key] = saveData[key];
                }
            }
        }
    }

    clearData() {
        localStorage.removeItem(this.storageKey);
        this.channel.postMessage(
            JSON.stringify({
                id: this.formId,
                data: null,
            })
        );
    }

    debounce(fun: Function, wait: number) {
        let timer: NodeJS.Timeout | null = null;
        return (...args: any[]) => {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(() => fun.apply(this, args), wait);
        };
    }

    echoData(data: any) {
        if (data) {
            for (const key in data) {
                if (Object.prototype.hasOwnProperty.call(data, key)) {
                    this.formData[key] = data[key];
                }
            }
        }
    }

    static clearAll() {
        const removes = Object.keys(localStorage).filter(key => key.startsWith("formData_"));
        console.log("🚀 ~ FormStorage ~ clearAll ~ removes:", removes);
        removes.forEach(key => localStorage.removeItem(key));
        const channel = new BroadcastChannel("formData_channel");
        channel.postMessage(
            JSON.stringify({
                id: "clearAll",
                data: null,
            })
        );
    }
}

class FormStorageManager {
    static instance: FormStorage[] = [];
    static isInitialized = false;
    static regist(instance: FormStorage) {
        FormStorageManager.instance.push(instance);
        if (!FormStorageManager.isInitialized) {
            window.addEventListener("beforeunload", FormStorageManager.saveAll);
            document.addEventListener("visibilitychange", FormStorageManager.handleVisibilitychange);
            FormStorageManager.isInitialized = true;
        }
    }

    static saveAll() {
        FormStorageManager.instance.forEach(instance => instance.saveData());
    }

    static handleVisibilitychange() {
        if (document.visibilityState === "hidden") {
            FormStorageManager.saveAll();
        }
    }
}

export default FormStorage;
